#ifndef AUTOMATON_H
#define AUTOMATON_H
#include<vector>
using std::vector;
#include<set>
using std::set;
#include<string>
using std::string;

class Automaton{
	private:
	int count;
	
	set<int> acceptingState;
	typedef vector< vector< vector<int>  > > translateTable;
	translateTable table;

	public:
	Automaton(unsigned int state,unsigned  int inputTable):table(state){
		for( unsigned int i = 0 ;  i  < state ; ++i){
			table[i].resize(inputTable);
		}
	}	
	template<class T>
	void AddAcceptState(T& begin,T& end){
		while(begin != end){
			acceptingState.insert(*begin);
			++begin;
		}
	}

	void AddAcceptState(int value){
		acceptingState.insert(value);
	}

	void RemoveAcceptingState(int value){
		acceptingState.erase(value);
	}

	template<class T>
	void Translate(int state,int input,T& beginResult, T& endResult){
		table[state][input].clear();
		while(beginResult != endResult){
			table[state][input].push_back(*beginResult);
			++beginResult;
		}
	}

	void Translate(int state,int input, int result){
		table[state][input].clear();
		table[state][input].push_back(result);
	}

	int Translate(int state,int input){
		if(state < 0 || input < 0){
			return -1;
		}
		if(table[state][input].size() == 0){
			return -1;
		}
		else{
	
			return table[state][input][0];
		}
	}
	
	bool Accpect(int state){
		if(acceptingState.find(state) == acceptingState.end()){
			return false;
		}
		return true;
	}
	
	bool  Match(string& m){
		
		int state = 0;
	    unsigned int i = 0;
		do{
		unsigned int input = this->TranslateInput(m[i++]);
		state = this->Translate(state,input);
			
		}while(this->Accpect(state) && i < m.size() );

		if(this->Accpect(state)){
			return true;
		}
		else{
			return false;
		}
	}

	virtual unsigned int TranslateInput(unsigned char ch) = 0;
};
#endif
